package org.jsets.fastboot.routingds.impl;

import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.jsets.fastboot.util.StringUtils;
import org.jsets.fastboot.routingds.config.DataSourceHolder;
import org.jsets.fastboot.routingds.jdbctemplateplus.JdbcTemplatePlus;
import com.google.common.collect.Maps;

/**
 * 
 * 
 * @author wj596
 *
 */
public class RoutingJdbcTemplate {

	private JdbcTemplatePlus primaryJdbcTemplate;
	private final Map<String, JdbcTemplatePlus> jdbcTemplates = Maps.newHashMap();
	private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

	public JdbcTemplatePlus getPrimary() {
		if (null != primaryJdbcTemplate) {
			return primaryJdbcTemplate;
		}

		this.lock.writeLock().lock();
		try {
			if (null != primaryJdbcTemplate) {
				return primaryJdbcTemplate;
			}

			primaryJdbcTemplate = new JdbcTemplatePlus(DataSourceHolder.getPrimaryDataSource());
			primaryJdbcTemplate.afterPropertiesSet();
			return primaryJdbcTemplate;
		} finally {
			this.lock.writeLock().unlock();
		}
	}

	public JdbcTemplatePlus getCurrent() {
		String currentDataSourceName = RoutingDataSourceContext.peek();
		if (StringUtils.isEmpty(currentDataSourceName)) {
			return getPrimary();
		}
		return this.getByName(currentDataSourceName);
	}

	public JdbcTemplatePlus getByName(String dataSourceName) {
		JdbcTemplatePlus template = null;
		this.lock.readLock().lock();
		template = this.jdbcTemplates.get(dataSourceName);
		this.lock.readLock().unlock();
		if (template != null) {
			return template;
		}

		this.lock.writeLock().lock();
		try {
			if (this.jdbcTemplates.containsKey(dataSourceName)) {
				return this.jdbcTemplates.get(dataSourceName);
			}
			template = new JdbcTemplatePlus(DataSourceHolder.getDataSources().get(dataSourceName));
			jdbcTemplates.put(dataSourceName, template);
			template.afterPropertiesSet();
			return template;
		} finally {
			this.lock.writeLock().unlock();
		}
	}
}